package com.zyw.orm.mybatis;

import com.zyw.orm.support.BaseEntity;
import com.zyw.orm.support.page.Page;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.support.DaoSupport;

import java.io.Serializable;
import java.util.List;

/**
 * @author zhangyw
 * @date 16/10/9 16:33
 */
public abstract class MybatisBaseDao2Impl<T extends BaseEntity, PK extends Serializable> extends DaoSupport implements MybatisBaseDao<T, PK> {

    @Autowired
    protected SqlSessionTemplate sqlSessionTemplate;

    /**
     * 获取mybatis文件中 映射的 mapper namespace
     *
     * @return namespace
     */
    protected abstract String getNamespace();

    private String getSelectStatement() {
        return getNamespace() + ".selectByPrimaryKey";
    }

    private String getDeleteByIdStatement() {
        return getNamespace() + ".deleteByPrimaryKey";
    }

    private String getDeleteStatement() {
        return getNamespace() + ".delete";
    }

    private String getInsertStatement() {
        return getNamespace() + ".insert";
    }

    private String getInsertSelectiveStatement() {
        return getNamespace() + ".insertSelective";
    }

    private String getUpdateStatement() {
        return getNamespace() + ".updateByPrimaryKey";
    }

    private String getUpdateSelectiveStatement() {
        return getNamespace() + ".updateByPrimaryKeySelective";
    }

    private String getFindListStatement() {
        return getNamespace() + ".findList";
    }

    /**
     * 获取单条数据
     *
     * @param id pk
     * @return
     */
    @Override
    public T get(PK id) {
        return this.sqlSessionTemplate.selectOne(getSelectStatement(), id);
    }

    /**
     * 查询数据列表
     *
     * @param entity
     * @return
     */
    @Override
    public List<T> findList(T entity) {
        return this.sqlSessionTemplate.selectList(getFindListStatement(), entity);
    }

    @Override
    public <E> Page<E> findPage(Page<E> page) {
        String statement = getNamespace() + ".findPage";
        return findPage(statement, page);
    }

    public <E> Page<E> findPage(String statement, Page<E> page) {

        if (-1 == page.getPageSize()) {
            List<E> list = this.sqlSessionTemplate.selectList(statement, page.getParamBean());
            page.setTotal(list == null ? 0 : list.size());
            page.setList(list);
            return page;
        }

        Integer total = this.sqlSessionTemplate.selectOne(statement + "Count", page.getParamBean());
        page.setTotal(total);

        if (page.isOutOfPage()) {
            return page;
        }

        RowBounds rowBounds = new RowBounds((page.getPageNo() - 1) * page.getPageSize(), page.getPageSize());

        List<E> list = this.sqlSessionTemplate.selectList(statement, page.getParamBean(), rowBounds);
        page.setList(list);
        return page;
    }

    /**
     * 插入数据
     *
     * @param entity
     * @return
     */
    @Override
    public int insert(T entity) {
        return this.sqlSessionTemplate.insert(getInsertStatement(), entity);
    }

    public int insertSelective(T entity) {
        return this.sqlSessionTemplate.insert(getInsertSelectiveStatement(), entity);
    }

    /**
     * 更新数据
     *
     * @param entity
     * @return
     */
    @Override
    public int update(T entity) {
        return this.sqlSessionTemplate.update(getUpdateStatement(), entity);
    }

    public int updateSelective(T entity) {
        return this.sqlSessionTemplate.update(getUpdateSelectiveStatement(), entity);
    }

    /**
     * 删除数据（一般为逻辑删除，更新del_flag字段为1）
     *
     * @param id
     * @return
     * @see public int delete(T entity)
     */
    @Override
    public int delete(PK id) {
        return this.sqlSessionTemplate.delete(getDeleteByIdStatement(), id);
    }

    /**
     * 删除数据
     *
     * @param entity
     * @return
     */
    @Override
    public int delete(T entity) {
        return this.sqlSessionTemplate.delete(getDeleteStatement(), entity);
    }


    @Override
    public Object executeSelectOne(String statement) {
        return this.sqlSessionTemplate.selectOne(statement);
    }

    @Override
    public Object executeSelectOne(String statement, Object params) {
        return this.sqlSessionTemplate.selectOne(statement, params);
    }

    @Override
    public Object executeQuery(String statement) {
        return this.sqlSessionTemplate.selectList(statement);
    }

    @Override
    public Object executeQuery(String statement, Object params) {
        return this.sqlSessionTemplate.selectList(statement, params);
    }

    @Override
    public Object executeUpdate(String statement, Object params) {
        return this.sqlSessionTemplate.update(statement, params);
    }

    @Override
    public Object executeInsert(String statement, Object params) {
        return this.sqlSessionTemplate.insert(statement, params);
    }

    public SqlSessionTemplate getSqlSessionTemplate() {
        return this.sqlSessionTemplate;
    }

    @Override
    protected void checkDaoConfig() throws IllegalArgumentException {
        if (sqlSessionTemplate == null)
            throw new IllegalArgumentException("sqlSession con't be null , please check");
    }
}
